//
//  main.m
//  07-内存管理
//
//  Created by 402030900@qq.com on 16/7/12.
//  Copyright © 2016年 402030900@qq.com. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Man.h"
int main(int argc, const char * argv[]) {
// 内存问题:
    // 一.内存溢出
    // 内存过多导致溢出,产生Crash
    // 二.野指针 (过度释放)
    // 指针指向未知区域,指向一块被释放的内存
    // 内存管理方式
    // 1.垃圾回收机制: 只有Mac上有
    // iOS
    // 2.MRC: 手动管理引用计数
    // 3.ARC: 自动管理引用计数(现在常用)
    // 注意: ARC基于MRC进行管理,系统帮程序员添加了内存管理的内容
    
    // 遇到retain、alloc、copy需要进行内存管理
//    NSObject * objc= [[NSObject alloc]init];
//    [objc retain];
//    [objc release];
//    [objc release];
    
    // 内存管理: 引用计数(计数器)
    // 有retain、alloc、copy 会对引用计数 + 1
    // 有release、autorelease 会对引用计数 － 1
    // 当对象的计数器为0的时候,系统会调用对应的dealloc方法
    
    // 1.MRC
    // 注意:  内存管理 你对对象完成后,再进行释放
    Man * man = [[Man alloc]init];
    NSLog(@"%ld",man.retainCount);
    [man retain];
    [man release];
    NSLog(@"%@,%ld",man,man.retainCount);
    
    // 集合类型,会对对象进行引用计数
    // addObject 对 对象进行引用计数 + 1
    // removeObject 对 对象进行引用计数 - 1
    NSMutableArray * array = [NSMutableArray arrayWithObjects:man, nil];
    NSLog(@"向数组中添加后的引用计数 %ld",man.retainCount);
    [array removeAllObjects];
    NSLog(@"从数组移除后的引用计数 %ld",man.retainCount);
    
    // 2.ARC
    // strong(ARC,强引用,引用计数 + 1) weak(应用于对象类型(NSObject子类),弱引用,对象被释放时,会自动置空)
    // retain(MRC,强引用,引用计数 + 1) assign
    // copy(拷贝,把对象拷贝一份,原来的引用计数不变,新的 + 1)
    // assign(应用于简单地数据类型,不会产生引用计数)
    
    // 协议
    // 1. 声明协议,声明协议方法
    // 2. 签订协议
    // 3. 实现协议方法
    
    // 如果想实现对象的拷贝
    // 1.签订协议NSCoping
    // 2.实现协议方法copyWithZone
    Man * newMan = [man copy];
    NSLog(@"newMan : %@ - oldMan : %@",newMan,man);
    
    // KVC(NSObject) Key-Value-Coding 键值编码 间接访问成员的方式
    // 只要是NSObject的子类就包含这些方法
    // valueForKey
    // valueForKeyPath
    // setValue: forKeyPath:
    newMan.name = @"韩旭";
    newMan.sexual = @"nv";
    id name = [newMan valueForKey:@"name"];
    NSLog(@"%@",name);
    [newMan setValue:@"徐康" forKey:@"name"];
    NSLog(@"%@",newMan.name);
    
    Man * gayMan = [[Man alloc]init];
    gayMan.gayBoy = newMan;
    id boyName = [gayMan valueForKeyPath:@"gayBoy.name"];
    NSLog(@"%@",boyName);
    [gayMan release];
    [gayMan setValue:@"李四" forKey:@"gayBoy.name"];
    NSLog(@"%@",gayMan.gayBoy.name);
    
//    NSDictionary * dic = [NSMutableDictionary dictionary];
//    [dic setValue:@"张三" forKey:@"name"];
//    NSLog(@"%@",dic);
    
    NSDictionary * dic = [[NSMutableDictionary alloc]initWithObjectsAndKeys:@"123456789",@"id",@"疯狂的健身康减肥呢",@"description", nil];
    Man * dicMan = [[Man alloc]init];
    [dicMan setValuesForKeysWithDictionary:dic];
    
    // 加在Build Phases下的编译source下
    //如果在ARC工程下使用MRC的文件
    // -fno-objc-arc
    // 在MRC的工程下使用ARC的文件
    // -fobjc-arc
    return 0;
}
